use List::*;

enum VeryVerboseEnumOfThingsToDoWithNumbers {
    Add,
    Subtract,
}

// 别名
type Op = VeryVerboseEnumOfThingsToDoWithNumbers;

// Self 别名
impl VeryVerboseEnumOfThingsToDoWithNumbers {
    fn run(&self, x: i32, y: i32) -> i32 {
        match self {
            Self::Add => x + y,
            Self::Subtract => x - y,
        }
    }
}
//use
enum Status {
    Rich,
    Poor,
}
enum Work {
    Civilian,
    Solider,
}
//C风格用法 enum
enum Number {
    Zero,
    One,
    Two,
}
enum Color {
    Red = 0xff0000,
    Green = 0x00ff00,
    Blue = 0x0000ff,
}
// 链表
enum List {
    Cons(u32, Box<List>),
    Nil,
}
//
impl List {
    fn new() -> List {
        Nil
    }

    fn prepend(self, elem: u32) -> List {
        Cons(elem, Box::new(self))
    }

    fn len(&self) -> u32 {
        match *self {
            Cons(_, ref tail) => 1 + tail.len(),
            Nil => 0,
        }
    }

    fn stringify(&self) -> String {
        match *self {
            Cons(head, ref tail) => {
                format!("{} {}", head, tail.stringify())
            }
            Nil => {
                format!("Nil")
            }
        }
    }
}
fn main() {
    let add = Op::Add;
    let sub = Op::Subtract;
    let x = add.run(1, 2);
    let y = sub.run(2, 1);
    println!("{} , {} ", x, y);

    //use
    use Status::{Poor, Rich};
    use Work::*;

    let status = Poor;
    let work = Solider;
    match status {
        Rich => println!("rich"),
        Poor => println!("poor"),
    };
    match work {
        Civilian => println!("c"),
        Solider => println!("solid"),
    };
    //
    println!("zero is {}", Number::Zero as i32);
    println!("One is {}", Number::One as i32);
    println!("Two is {}", Number::Two as i32);
    //
    println!("Red is {:06x}", Color::Red as i32);
    println!("Green is {:06x}", Color::Green as i32);
    println!("Blue is {:06x}", Color::Blue as i32);
    //
    let mut list = List::new();
    list = list.prepend(1);
    list = list.prepend(2);
    list = list.prepend(3);
    println!("length is {}", list.len());
    println!("{}", list.stringify());
}
